/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
 * Description: RDMA CC context.
 * Create: 2021-12-30
 */

#ifndef ROCE_CCF_FORMAT_H
#define ROCE_CCF_FORMAT_H

/* Align each field with 4bytes. */
#pragma pack(4)

#ifndef BIG_ENDIAN
#define BIG_ENDIAN    0x4321
#endif

#ifndef LITTLE_ENDIAN
#define LITTLE_ENDIAN    0x1234
#endif

enum ROCE3_CCF_PARAM_ALGO_ID {
    ROCE_CCF_ALGO_ID,
    ROCE_DCQCN_ALGO_ID,
    ROCE_HC3_2_0_ALGO_ID,
    ROCE_LDCP_ALGO_ID,
    ROCE_MIBO_ALGO_ID,
    ROCE_BW_CTRL_ALGO_ID,
    ROCE_CCF_PARAM_MAX_ID = 7
};
#define ROCE_IPQCN_ALGO_ID ROCE_DCQCN_ALGO_ID
#define ROCE_CCF_PARAM_INDEX_GET(vf_id, algo_id) (((vf_id) << 3) | (algo_id))

enum ROCE_CC_ALGO_E {
    ROCE_CC_DISABLE = 0,
    ROCE_CC_DCQCN_ALGO,
    ROCE_CC_LDCP_ALGO,
    ROCE_CC_IPQCN_ALGO,
    ROCE_CC_MIBO_ALGO
};

#define CTX_TBL_WR_KEY_OFFSET 16
#define CTX_TBL_CPY_BYTE_TYPE 48

/* *************************** QPC *************************** */
typedef struct ucode_ccf_sq_ctx {
    /* DW0 */
    union {
        struct {
#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
            u32 rsvd : 12;
            u32 retrans_read_req : 1;
            u32 retrans_mark : 1;
            u32 sw_send_sn : 16;
            u32 sw_wnd_timer_stat : 2;
#else
            u32 sw_wnd_timer_stat : 2;
            u32 sw_send_sn : 16;
            u32 retrans_mark : 1;
            u32 retrans_read_req : 1;
            u32 rsvd : 12;
#endif
        } ldcpw;

        u32 value;
    } dw0;
} ucode_ccf_sq_ctx_s;

typedef struct ucode_ccf_sqa_ctx {
    /* DW0 */
    union {
        struct {
#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
            u32 rsvd : 6;
            u32 sw_zero_avail_wnd : 1;
            u32 rr_zero_avail_wnd : 1;
            u32 change2rqa_stg_cnt : 8;
            u32 rr_rcv_sn : 16;
#else
            u32 rr_rcv_sn : 16;
            u32 change2rqa_stg_cnt : 8;
            u32 rr_zero_avail_wnd : 1;
            u32 sw_zero_avail_wnd : 1;
            u32 rsvd : 6;
#endif
        } ldcpw;

        u32 value;
    } dw0;

    /* DW1 */
    union {
        struct {
#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
            u32 sw_ack_sn : 16;
            u32 rr_ack_sn : 16;
#else
            u32 rr_ack_sn : 16;
            u32 sw_ack_sn : 16;
#endif
        } ldcpw;

        u32 value;
    } dw1;
} ucode_ccf_sqa_ctx_s;

typedef struct ucode_ccf_rq_ctx {
    /* DW0 */
    union {
        struct {
#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
            u32 sw_rcv_sn : 16;
            u32 rcv_timestamp : 16;
#else
            u32 rcv_timestamp : 16;
            u32 sw_rcv_sn : 16;
#endif
        } ldcpw;

        u32 value;
    } dw0;
} ucode_ccf_rq_ctx_s;

typedef struct ucode_ccf_rqa_ctx {
    /* DW0 */
    union {
        struct {
#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
            u32 rr_send_sn : 16;
            u32 rr_send_ce_sn : 11;
            u32 rr_rsp_ack_cnt : 1;
            u32 rcv_read_rsp : 1;
            u32 ext_hdr_flip : 1;
            u32 rr_wnd_timer_stat : 2;
#else
            u32 rr_wnd_timer_stat : 2;
            u32 ext_hdr_flip : 1;
            u32 rcv_read_rsp : 1;
            u32 rr_rsp_ack_cnt : 1;
            u32 rr_send_ce_sn : 11;
            u32 rr_send_sn : 16;
#endif
        } ldcpw;

        u32 value;
    } dw0;
} ucode_ccf_rqa_ctx_s;

/* *************************** EXT TABLE *************************** */
/* ccf common param tbl */
typedef struct roce_ccf_param {
    union {
        struct {
#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
            u32 np_enable : 8;
            u32 rp_enable : 8;
            u32 ecn_ver : 4;
            u32 cnp_prio_enable : 1;
            u32 ip_enable : 8;
            u32 port_mode : 1;
            u32 rsvd : 2;
#else
            u32 rsvd : 2;
            u32 port_mode : 1;
            u32 ip_enable : 8;
            u32 cnp_prio_enable : 1;
            u32 ecn_ver : 4;
            u32 rp_enable : 8;
            u32 np_enable : 8;
#endif
        } bs;
        u32 value;
    } dw0;

    union {
        struct {
#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
            u32 cnp_cos : 3;
            u32 cnp_prio : 3;
            u32 ccf_appid : 8;
            u32 rsvd : 18;
#else
            u32 rsvd : 18;
            u32 ccf_appid : 8;
            u32 cnp_prio : 3;
            u32 cnp_cos : 3;
#endif
        } bs;
        u32 value;
    } dw1;

    u32 rsvd[2];
} roce_ccf_param_s;

typedef struct roce_dcqcn_param {
    union {
        struct {
#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
            u32 rsvd : 18;
            u32 flow_min_rate : 6;
            u32 token_period : 8;
#else
            u32 token_period : 8;
            u32 flow_min_rate : 6;
            u32 rsvd : 18;
#endif
        } bs;
        u32 value;
    } dw0;

    union {
        struct {
#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
            u32 rate_inc_period : 10;
            u32 rsvd : 3;
            u32 cnp_cnt_threshold : 4;
            u32 alpha_dec_period : 10;
            u32 alpha_threshold : 5;
#else
            u32 alpha_threshold : 5;
            u32 alpha_dec_period : 10;
            u32 cnp_cnt_threshold : 4;
            u32 rsvd : 3;
            u32 rate_inc_period : 10;
#endif
        } bs;

        struct {
#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
            u32 rate_inc_period : 16;
            u32 alpha_dec_period : 16;
#else
            u32 alpha_dec_period : 16;
            u32 rate_inc_period : 16;
#endif
        } bs1;
        u32 value;
    } dw1;

    union {
        struct {
#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
            u32 rate_inc_ai : 8;
            u32 rate_inc_hai : 8;
            u32 rate_dec_period : 8;
            u32 min_cnp_period : 8;
#else
            u32 min_cnp_period : 8;
            u32 rate_dec_period : 8;
            u32 rate_inc_hai : 8;
            u32 rate_inc_ai : 8;
#endif
        } bs;
        u32 value;
    } dw2;

    union {
        struct {
#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
            u32 factor_gita : 4;
            u32 rt_clamp : 1;
            u32 rsvd : 1;
            u32 initial_alpha : 10;
            u32 rate_first_set : 16;
#else
            u32 rate_first_set : 16;
            u32 initial_alpha : 10;
            u32 rsvd : 1;
            u32 rt_clamp : 1;
            u32 factor_gita : 4;
#endif
        } bs;
        u32 value;
    } dw3;
} roce_dcqcn_param_s;

typedef struct roce_ipqcn_param {
    union {
        struct {
#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
            u32 rsvd : 18;
            u32 flow_min_rate : 6;
            u32 token_period : 8;
#else
            u32 token_period : 8;
            u32 flow_min_rate : 6;
            u32 rsvd : 18;
#endif
        } bs;
        u32 value;
    } dw0;

    union {
        struct {
#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
            u32 rate_inc_period : 10;
            u32 rsvd : 3;
            u32 cnp_cnt_threshold : 4;
            u32 alpha_dec_period : 10;
            u32 alpha_threshold : 5;
#else
            u32 alpha_threshold : 5;
            u32 alpha_dec_period : 10;
            u32 cnp_cnt_threshold : 4;
            u32 rsvd : 3;
            u32 rate_inc_period : 10;
#endif
        } bs;

        struct {
#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
            u32 rate_inc_period : 16;
            u32 alpha_dec_period : 16;
#else
            u32 alpha_dec_period : 16;
            u32 rate_inc_period : 16;
#endif
        } bs1;
        u32 value;
    } dw1;

    union {
        struct {
#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
            u32 rate_inc_ai : 8;
            u32 rate_inc_hai : 8;
            u32 rate_dec_period : 8;
            u32 min_cnp_period : 8;
#else
            u32 min_cnp_period : 8;
            u32 rate_dec_period : 8;
            u32 rate_inc_hai : 8;
            u32 rate_inc_ai : 8;
#endif
        } bs;
        u32 value;
    } dw2;

    union {
        struct {
#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
            u32 factor_gita : 4;
            u32 rt_clamp : 1;
            u32 rsvd : 1;
            u32 initial_alpha : 10;
            u32 rate_first_set : 16;
#else
            u32 rate_first_set : 16;
            u32 initial_alpha : 10;
            u32 rsvd : 1;
            u32 rt_clamp : 1;
            u32 factor_gita : 4;
#endif
        } bs;
        u32 value;
    } dw3;
} roce_ipqcn_param_s;

typedef struct roce_ldcp_param {
    union {
        struct {
#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
            u32 alpha : 2;
            u32 beta : 2;
            u32 gamma : 2;
            u32 eta : 2;
            u32 set_flag : 1;
            u32 rsvd : 23;
#else
            u32 rsvd : 23;
            u32 set_flag : 1;
            u32 eta : 2;
            u32 gamma : 2;
            u32 beta : 2;
            u32 alpha : 2;
#endif
        } bs;
        u32 value;
    } dw0;
 
    u32 rsvd1[3];
} roce_ldcp_param_s;

typedef struct ucode_ext_table_sq_ctx {
    /* DW0 */
    union {
        u32 ldcpw_rsvd;

        u32 value;
    } dw0;

    u32 rsvd;
} ucode_ext_table_sq_ctx_s;

typedef struct ucode_ext_table_sqa_ctx {
    /* DW0 */
    union {
        struct {
#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
            u32 rsvd : 21;
            u32 rr_rcv_ce_sn : 11;
#else
            u32 rr_rcv_ce_sn : 11;
            u32 rsvd : 21;
#endif
        } ldcpw;

        u32 value;
    } dw0;

    u32 rsvd;
} ucode_ext_table_sqa_ctx_s;

typedef struct ucode_ext_table_rq_ctx {
    /* DW0 */
    union {
        struct {
#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
            u32 rsvd : 20;
            u32 sw_rcv_ce_sn : 12;
#else
            u32 sw_rcv_ce_sn : 12;
            u32 rsvd : 20;
#endif
        } ldcpw;

        u32 value;
    } dw0;

    u32 rsvd;
} ucode_ext_table_rq_ctx_s;

typedef struct ucode_ext_table_rqa_ctx {
    /* DW0 */
    union {
        struct {
#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && ((BYTE_ORDER == BIG_ENDIAN))
            u32 rsvd : 20;
            u32 sw_send_ce_sn : 12;
#else
            u32 sw_send_ce_sn : 12;
            u32 rsvd : 20;
#endif
        } ldcpw;

        u32 value;
    } dw0;

    u32 rsvd;
} ucode_ext_table_rqa_ctx_s;
typedef struct ucode_ext_table_qpc_ctx {
    ucode_ext_table_sq_ctx_s sq;
    ucode_ext_table_sqa_ctx_s sqa;
    ucode_ext_table_rq_ctx_s rq;
    ucode_ext_table_rqa_ctx_s rqa;
} ucode_ext_table_qpc_ctx_s;

#pragma pack(0)

#endif // ROCE_CCF_FORMAT_H
